<template>
  <div class="log-monitor">
    <div class="header">
      <h2>实时日志监控</h2>
      <div class="controls">
        <el-button 
          v-if="!connected" 
          type="primary" 
          icon="el-icon-video-play" 
          @click="connectWebSocket"
          :loading="connecting">
          {{ connecting ? '连接中...' : '连接' }}
        </el-button>
        <el-button 
          v-else 
          type="danger" 
          icon="el-icon-switch-button" 
          @click="disconnectWebSocket">
          断开
        </el-button>
        
        <el-button 
          type="info" 
          icon="el-icon-delete" 
          @click="clearLogs"
          :disabled="logs.length === 0">
          清空日志
        </el-button>
        
        <el-checkbox v-model="autoScroll" class="auto-scroll">自动滚动</el-checkbox>
        
        <div class="status">
          <span class="status-indicator" :class="statusClass"></span>
          {{ statusText }}
        </div>
      </div>
    </div>
    
    <div class="filter-bar">
      <el-input 
        v-model="searchText" 
        placeholder="搜索日志内容" 
        prefix-icon="el-icon-search"
        clearable
        style="width: 300px; margin-right: 10px;">
      </el-input>
      
      <el-select v-model="logLevel" placeholder="日志级别" clearable style="width: 120px;">
        <el-option label="全部" value=""></el-option>
        <el-option label="INFO" value="INFO"></el-option>
        <el-option label="WARN" value="WARN"></el-option>
        <el-option label="ERROR" value="ERROR"></el-option>
      </el-select>
      
      <span class="stats">日志行数: {{ filteredLogs.length }}/{{ logs.length }}</span>
    </div>
    
    <div class="log-container" ref="logContainer">
      <div v-if="filteredLogs.length === 0" class="empty-logs">
        {{ logs.length === 0 ? '暂无日志数据' : '没有匹配的日志' }}
      </div>
      
      <div 
        v-for="(log, index) in filteredLogs" 
        :key="index" 
        class="log-line"
        :class="'level-' + log.level.toLowerCase()">
        <span class="log-time">[{{ log.timestamp }}]</span>
        <span class="log-level">[{{ log.level }}]</span>
        <span class="log-message">{{ log.message }}</span>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'LogMonitor',
  data() {
    return {
      ws: null,
      connected: false,
      connecting: false,
      logs: [],
      autoScroll: true,
      searchText: '',
      logLevel: '',
      wsUrl: '' // 请根据实际情况修改
    }
  },
  computed: {
    statusClass() {
      if (this.connected) return 'status-connected';
      if (this.connecting) return 'status-connecting';
      return 'status-disconnected';
    },
    statusText() {
      if (this.connected) return '已连接';
      if (this.connecting) return '连接中';
      return '未连接';
    },
    filteredLogs() {
      let filtered = this.logs;
      
      // 按日志级别过滤
      if (this.logLevel) {
        filtered = filtered.filter(log => log.level === this.logLevel);
      }
      
      // 按搜索文本过滤
      if (this.searchText) {
        const keyword = this.searchText.toLowerCase();
        filtered = filtered.filter(log => 
          log.message.toLowerCase().includes(keyword) || 
          log.timestamp.includes(keyword)
        );
      }
      
      return filtered;
    }
  },
  watch: {
    // 监听日志变化，实现自动滚动
    filteredLogs: {
      handler() {
        this.$nextTick(() => {
          if (this.autoScroll) {
            this.scrollToBottom();
          }
        });
      },
      deep: true
    }
  },
  created() {
    this.wsUrl = process.env.VUE_APP_WS_URL
  },
  mounted() {
    // 组件挂载后自动连接WebSocket
    this.connectWebSocket();
  },
  beforeDestroy() {
    // 组件销毁前断开WebSocket连接
    this.disconnectWebSocket();
  },
  methods: {
    connectWebSocket() {
      if (this.connected || this.connecting) return;
      
      this.connecting = true;
      
      try {
        const url = this.wsUrl + "/websocket/message/9996";
        this.ws = new WebSocket(url);
        
        this.ws.onopen = () => {
          console.log('WebSocket连接成功');
          this.connected = true;
          this.connecting = false;
          this.$message.success('WebSocket连接成功');
        };
        
        this.ws.onmessage = (event) => {
          // 假设后端推送的数据格式为JSON: {timestamp: '时间', level: '级别', message: '日志内容'}
          try {
            const logData = JSON.parse(event.data);
            this.addLog(logData);
          } catch (e) {
            // 如果数据不是JSON格式，直接作为消息处理
            this.addLog({
              timestamp: new Date().toLocaleTimeString(),
              level: 'INFO',
              message: event.data
            });
          }
        };
        
        this.ws.onerror = (error) => {
          console.error('WebSocket错误:', error);
          this.connecting = false;
          this.$message.error('WebSocket连接错误');
        };
        
        this.ws.onclose = () => {
          console.log('WebSocket连接关闭');
          this.connected = false;
          this.connecting = false;
        };
      } catch (error) {
        console.error('创建WebSocket失败:', error);
        this.connecting = false;
        this.$message.error('创建WebSocket连接失败');
      }
    },
    
    disconnectWebSocket() {
      if (this.ws) {
        this.ws.close();
        this.ws = null;
      }
      this.connected = false;
      this.connecting = false;
    },
    
    addLog(logData) {
      // 确保日志数据有必要的字段
      const log = {
        timestamp: logData.timestamp || new Date().toLocaleTimeString(),
        level: logData.level || 'INFO',
        message: logData.message || String(logData)
      };
      
      this.logs.push(log);
      
      // 限制日志数量，避免内存溢出
      if (this.logs.length > 1000) {
        this.logs = this.logs.slice(-500);
      }
    },
    
    clearLogs() {
      this.logs = [];
    },
    
    scrollToBottom() {
      const container = this.$refs.logContainer;
      if (container) {
        container.scrollTop = container.scrollHeight;
      }
    }
  }
}
</script>

<style scoped>
.log-monitor {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: 100vh;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  background-color: #fff;
  padding: 15px 20px;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.header h2 {
  margin: 0;
  color: #303133;
}

.controls {
  display: flex;
  align-items: center;
  gap: 10px;
}

.auto-scroll {
  margin-left: 10px;
}

.status {
  display: flex;
  align-items: center;
  color: #606266;
  font-size: 14px;
}

.status-indicator {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 5px;
}

.status-connected {
  background-color: #67c23a;
}

.status-disconnected {
  background-color: #f56c6c;
}

.status-connecting {
  background-color: #e6a23c;
}

.filter-bar {
  display: flex;
  align-items: center;
  margin-bottom: 15px;
  background-color: #fff;
  padding: 15px 20px;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.stats {
  margin-left: auto;
  color: #909399;
  font-size: 14px;
}

.log-container {
  height: 600px;
  overflow-y: auto;
  background-color: #1e1e1e;
  color: #d4d4d4;
  font-family: 'Courier New', monospace;
  padding: 15px;
  border-radius: 4px;
  white-space: pre-wrap;
  word-break: break-all;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.empty-logs {
  text-align: center;
  color: #666;
  padding: 20px;
}

.log-line {
  line-height: 1.5;
  border-bottom: 1px solid #2d2d2d;
  padding: 5px 0;
  display: flex;
}

.log-line:last-child {
  border-bottom: none;
}

.log-time {
  color: #6a9955;
  min-width: 80px;
  margin-right: 10px;
}

.log-level {
  min-width: 50px;
  margin-right: 10px;
}

.level-info .log-level {
  color: #569cd6;
}

.level-warn .log-level {
  color: #ffcc02;
}

.level-error .log-level {
  color: #f44747;
}

.log-message {
  flex: 1;
}
</style>